package com.budwk.app.sqfwV2.component;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.SqfwPdfCreateCommonBO;
import com.budwk.app.sqfwV2.dto.dto.ExtraProblemVo;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.AccommodatePeopleVo;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.ProblemParamDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.SandwichingVo;
import com.budwk.app.sqfwV2.enums.RectificateTimeEnum;
import com.budwk.app.sqfwV2.enums.dayingRoad.KeySafetyIndustriesEnum;
import com.budwk.app.sqfwV2.enums.dayingRoad.OtherPatrolContentsEnum;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.RenderPolicy;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 问题公共服务实现类
 */

@Slf4j
public class ProblemComponent {

    // 用于下载模板使用
    public static final String DOWNIDS_TEMPLATE_IDS = "20240649522c7ad274fa5b7ae527c1527e92126";

    private static void buildFires(SafeCheckTaskParamDataDTO s, List<SafeCheckTaskParamDataDTO> safes) {
        if (s == null) {
            return;
        }
        Boolean isRectification = s.getIsRectification();
        if (isRectification != null) {
            String problemDesc = s.getProblemDesc();
            if (StringUtils.isNotEmpty(problemDesc)) {
                SafeCheckTaskParamDataDTO safe = new SafeCheckTaskParamDataDTO();
                safe.setProblemDesc(problemDesc).setIsRectification(isRectification).setRiskImages(s.getRiskImages()).setRectificationBackPhoto(s.getRectificationBackPhoto());
                safes.add(safe);
            }
        }
    }

    /**
     * 未配备消防问题 （以前的a24）问题
     */
    public static List<SafeCheckTaskParamDataDTO> getFireIssues(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        SandwichingVo sandwichingVo = roadPdfDTO.getSandwichConstructionUse();
        List<SafeCheckTaskParamDataDTO> safes = new ArrayList<>();
        if (sandwichingVo != null) {
            buildFires(sandwichingVo.getMezzaninFfloorSlab(), safes);
            buildFires(sandwichingVo.getStaircaseBuildingMaterials(), safes);
        }
        // 1 住人形式
        AccommodatePeopleVo a = roadPdfDTO.getAccommodatePeople();
        if (a != null) {
            // 经营范围是旅馆时 不算隐患
            Boolean isRectification = a.getIsRectification();
            if (isRectification != null) {
                String problemDesc = a.getProblemDesc();
                if (StringUtils.isNotEmpty(problemDesc)) {
                    SafeCheckTaskParamDataDTO safe = new SafeCheckTaskParamDataDTO();
                    safe.setProblemDesc(problemDesc).setIsRectification(isRectification)
                            .setRiskImages(a.getViolationPhoto()).setRectificationBackPhoto(a.getRectificationAfterPhoto());;
                    safes.add(safe);
                }
            }
        }
        // 2 配备灭火器
//        buildFires(roadPdfDTO.getWhetherEquippedFire(), safes);
        // 3 电气线路乱拉乱接
        buildFires(roadPdfDTO.getElectricalCircuitSituation(), safes);
        // 4 电动自行车使用情况
        buildFires(roadPdfDTO.getElectricBicyclesUse(), safes);
        // 5 使用明火高温
        buildFires(roadPdfDTO.getFireHighUsageArea(), safes);
        // 6 是否存放易燃易爆危险品
        buildFires(roadPdfDTO.getIsCombustiblEexplosive(), safes);
        // 8 其他巡查内容
        ExtraProblemVo extraOtherParam = roadPdfDTO.getExtraOtherParam();
        if (extraOtherParam != null) {
            List<SafeCheckTaskParamDataDTO> existProblems = extraOtherParam.getExistProblems();
            for (SafeCheckTaskParamDataDTO e : existProblems) {
                SafeCheckTaskParamDataDTO safe = new SafeCheckTaskParamDataDTO();
                safe.setProblemDesc(e.getRiskDesc()).setIsRectification(RectificateTimeEnum.isNowRectification(e.getRectificationTypeCode()))
                        .setRiskImages(e.getRiskImages()).setRectificationBackPhoto(e.getRectificationBackPhoto());
                safes.add(safe);
            }
        }
        // 消防设施的其他问题
        buildFires(roadPdfDTO.getFireOtherIssues(), safes);
        // 燃气报警器的数量
        buildFires(roadPdfDTO.getGasAlarmsNumber(), safes);
        // 报警器使用是否正常
        buildFires(roadPdfDTO.getIsAlarmNormal(), safes);
        // 7 其他隐患
        List<SafeCheckTaskParamDataDTO> others = roadPdfDTO.getOtherHiddenDangers();
        if (others != null && others.size() > 0) {
            for (SafeCheckTaskParamDataDTO e : others) {
                if (safes.size() > 0) {
                    SafeCheckTaskParamDataDTO safe = safes.get(0);
                    if (StringUtils.isEmpty(safe.getRiskImages())) {
                        safe.setRiskImages(e.getRiskImages());
                    }
                    if (StringUtils.isEmpty(safe.getRectificationBackPhoto())) {
                        safe.setRectificationBackPhoto(e.getRectificationBackPhoto());
                    }
                }
                buildFires(e, safes);
            }
        }
        List<SafeCheckTaskParamDataDTO> results = new ArrayList<>();
        if (safes.size() > 0) {
            for (int i = 0; i < safes.size(); i++) {
                SafeCheckTaskParamDataDTO s = safes.get(i);
                if (safes.size() == 1) {
                    s.setProblemDesc((i + 1) + " " +  s.getProblemDesc());
                    results.add(s);
                    break;
                }
                if (i == safes.size() - 1) {
                    s.setProblemDesc((i + 1) + " " + s.getProblemDesc() + ";");
                    results.add(s);
                    continue;
                }
                s.setProblemDesc((i + 1) + " " + s.getProblemDesc() + ";\n");
                results.add(s);
            }
        }
        return results;
    }

    /**
     * 隐患整改时限
     * @param roadPdfDTO
     * @return
     */
    public static String getDangerStr(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, LocalDate rectificationDate) {
        String rectificationStr = "无";
        List<String> problemDesc = KeySafetyIndustriesEnum.getProblemDesc(roadPdfDTO.getKeySafetyIndustries());
        if (problemDesc.size() == 0) {
            return rectificationStr;
        }
        // 没有整改 检查时间
        LocalDateTime inspectionDate = roadPdfDTO.getInspectionDate();
        inspectionDate = inspectionDate == null ? LocalDateTime.now() : inspectionDate;
        if (rectificationDate != null) {
            Duration between = LocalDateTimeUtil.between(inspectionDate, rectificationDate.atTime(LocalTime.now()));
            long days = between.toDays();
            if (days == 0) rectificationStr = "已当天整改";
            else rectificationStr = days + "天";
        }
        return rectificationStr;
    }

    /**
     * 是否存在安全隐患  25个 问题
     * @param roadPdfDTO
     * @return
     */
    public static String getSafeDescStr(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, ProblemParamDTO ppd) {

        List<String> list = new ArrayList<>();
        String lastSummaryId = roadPdfDTO.getLastSummaryId();
        FireSafetyOnDayingRoadPdfDTO lastVo = null;
        if (StringUtils.isNotEmpty(lastSummaryId)) {
            SqfwFormsummaryNewService formsummaryNewService = NutzIocUtils.getBean(SqfwFormsummaryNewService.class);
            Sqfw_formSummary_new formSummaryNew = formsummaryNewService.fetch(lastSummaryId);
            lastVo = JSONObject.parseObject(formSummaryNew.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
        }
        for (SafeCheckTaskParamDataDTO other : roadPdfDTO.getOtherPatrolContents()) {
            OtherPatrolContentsEnum industriesEnum = OtherPatrolContentsEnum.getEnumByCode(other.getFields());
            if (other.getKey().equals(industriesEnum.getDefaultValue())) {
                if (isLastDetermine(lastVo, industriesEnum)) {
                    ppd.setRemark("已整改");
                }
                continue;
            }
            list.add(industriesEnum.getDesc());
            if (RectificateTimeEnum.DEADLINE_RECTIFICATION.getCode().equals(other.getRectificationTypeCode())) {
                ppd.setRemark("期限整改");
            }
        }
        return list.size() > 0 ? "有异常" : "暂无异常";
    }

    /**
     * 消防安全设施储备情况  14 16 问题
     * @param roadPdfDTO
     * @return
     */
    public static String getReserveFireSafety(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, ProblemParamDTO ppd) {
        List<String> problemKeys = List.of(OtherPatrolContentsEnum.FORETEEN.getCode(), OtherPatrolContentsEnum.SIXTEEN.getCode());
        List<String> noDeDesc = getNoDeDesc(roadPdfDTO, problemKeys, ppd);
        return noDeDesc.size() > 0 ? "有异常" : "暂无异常";
    }

    /**
     * 钢瓶、管道、灶具等燃气用户状况  4 5 7 17 18 问题
     * @param roadPdfDTO
     * @return
     */
    public static String getGasStovesStr(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, ProblemParamDTO ppd) {
        List<String> problemKeys = List.of(OtherPatrolContentsEnum.FORE.getCode(), OtherPatrolContentsEnum.FIVE.getCode(),
                OtherPatrolContentsEnum.SEVEN.getCode(), OtherPatrolContentsEnum.SEVENTEEN.getCode(), OtherPatrolContentsEnum.EIGHTTEEN.getCode());
        List<String> noDeDesc = getNoDeDesc(roadPdfDTO, problemKeys, ppd);
        return noDeDesc.size() > 0 ? String.join(";", noDeDesc) : "灶具等燃气暂无异常";
    }

    private static List<String> getNoDeDesc(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, List<String> problemKeys, ProblemParamDTO p) {
        // 获取实体的描述信息
        List<SafeCheckTaskParamDataDTO> otherPatrolContents = roadPdfDTO.getOtherPatrolContents();
        if (otherPatrolContents == null || otherPatrolContents.size() == 0) {
            return ListUtil.empty();
        }
        FireSafetyOnDayingRoadPdfDTO lastVo = null;
        if (StringUtils.isNotEmpty(roadPdfDTO.getLastSummaryId())) {
            SqfwFormsummaryNewService formsummaryNewService = NutzIocUtils.getBean(SqfwFormsummaryNewService.class);
            Sqfw_formSummary_new formSummaryNew = formsummaryNewService.fetch(roadPdfDTO.getLastSummaryId());
            log.info(" getNoDeDesc roadPdfDTO -------------------------: {}", JSONObject.toJSONString(roadPdfDTO));
            lastVo = JSONObject.parseObject(formSummaryNew.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
        }
        List<String> desc = new ArrayList<>(10);
        for (String code : problemKeys) {
            Optional<SafeCheckTaskParamDataDTO> optional = otherPatrolContents.stream().filter(e -> e.getFields().equals(code)).findFirst();
            if (optional.isPresent()) {
                SafeCheckTaskParamDataDTO s = optional.get();
                OtherPatrolContentsEnum e = OtherPatrolContentsEnum.getEnumByCode(code);
                if (s.getKey().equals(e.getDefaultValue())) {
                    String lastSummaryId = roadPdfDTO.getLastSummaryId();
                    if (StringUtils.isEmpty(lastSummaryId)) {
                        continue;
                    }
                    if (isLastDetermine(lastVo, e)) {
                        p.setRemark("已整改");
                    }
                    continue;
                }
                desc.add(e.getDesc());
                if (RectificateTimeEnum.DEADLINE_RECTIFICATION.getCode().equals(s.getRectificationTypeCode())) {
                    p.setRemark("期限整改");
                }
            }
        }
        return desc;
    }

    /**
     * 判断上一条数据是否是期限整改
     * @param vo
     * @param defaultEnum
     * @return
     */
    private static boolean isLastDetermine(FireSafetyOnDayingRoadPdfDTO vo, OtherPatrolContentsEnum defaultEnum) {
        if (vo == null) {
            return false;
        }
        List<SafeCheckTaskParamDataDTO> otherPatrolContents = vo.getOtherPatrolContents();
        if (otherPatrolContents != null && otherPatrolContents.size() > 0) {
            Optional<SafeCheckTaskParamDataDTO> optional = otherPatrolContents.stream().filter(e -> e.getFields().equals(defaultEnum.getCode())).findFirst();
            if (optional.isPresent()) {
                SafeCheckTaskParamDataDTO safe = optional.get();
                if (safe.getKey().equals(defaultEnum.getDefaultValue())) {
                    return false;
                }
                if (StringUtils.isNotEmpty(safe.getRectificationTypeCode())) {
                    if (RectificateTimeEnum.DEADLINE_RECTIFICATION.getCode().equals(safe.getRectificationTypeCode())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 燃气存储地是否合规(含收市后存放地)
     */
    public static String getGasStoreStr(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, ProblemParamDTO p) {
        List<String> problemKeys = List.of(OtherPatrolContentsEnum.ONE.getCode(), OtherPatrolContentsEnum.TWO.getCode(),
                OtherPatrolContentsEnum.THREE.getCode(), OtherPatrolContentsEnum.ENGHT.getCode());
        List<String> noDeDesc = getNoDeDesc(roadPdfDTO, problemKeys, p);
        return noDeDesc.size() > 0 ? String.join(";", noDeDesc) : "燃气周边，存储周边整洁";
    }

    /**
     * 获取问题的key
     */
    public static SafeCheckTaskParamDataDTO getSafeCheckTaskParamDataDTO(List<SafeCheckTaskParamDataDTO> datas, String code) {
        Optional<SafeCheckTaskParamDataDTO> optional = datas.stream().filter(e -> e.getFields().equals(code)).findAny();
        return optional.orElse(null);
    }

    /**
     * 是否有隐患
     */
    public static boolean isHiveDanger(SafeCheckTaskParamDataDTO p) {
        if (p == null) {
            return false;
        }
        Boolean isRectification = p.getIsRectification();
        return isRectification != null;
    }

    /**
     * 组装额外的问题参数
     * @param defaultValues 所有问题的默认值
     * @param hiddenDanger 当前传递的问题
     * @return
     */
    public static ExtraProblemVo getExtraProblemVo(List<SafeCheckTaskParamDataDTO> defaultValues, List<SafeCheckTaskParamDataDTO> hiddenDanger) {
        if (hiddenDanger == null || hiddenDanger.size() == 0) {
            return null;
        }
        ExtraProblemVo extraProblemVo = new ExtraProblemVo();
        List<SafeCheckTaskParamDataDTO> existProblems = new ArrayList<>(); //存在的问题
        List<Integer> existProblemIds = new ArrayList<>(); //存在的问题编号
        List<Integer> existYesProblemIds = new ArrayList<>(); // 已整改的问题编号（全部整改，本此全是立即整改的数据）
        List<Integer> existNoProblemIds = new ArrayList<>(); // 未整改的问题编号（期限整改）
        Boolean isProblemAllOne = true;
        for (SafeCheckTaskParamDataDTO defaultValue : defaultValues) {
            Optional<SafeCheckTaskParamDataDTO> optional = hiddenDanger.stream().filter(e -> defaultValue.getFields().equals(e.getFields())).findFirst();
            if (optional.isPresent()) {
                SafeCheckTaskParamDataDTO safe = optional.get();
                if (!safe.getKey().equals(defaultValue.getKey())) {
                    isProblemAllOne = false;
                    existProblems.add(safe);
                    existProblemIds.add(Integer.valueOf(defaultValue.getRiskCode()));
                    if (RectificateTimeEnum.IMMEDIATE_RECTIFICAIOTN.getCode().equals(safe.getRectificationTypeCode())) {
                        existYesProblemIds.add(Integer.valueOf(defaultValue.getRiskCode()));
                    }
                    if (RectificateTimeEnum.DEADLINE_RECTIFICATION.getCode().equals(safe.getRectificationTypeCode())) {
                        existNoProblemIds.add(Integer.valueOf(defaultValue.getRiskCode()));
                    }
                }
            }
        }
        extraProblemVo.setExistProblems(existProblems)
                .setExistProblemIds(existProblemIds)
                .setExistYesProblemIds(existYesProblemIds)
                .setExistNoProblemIds(existNoProblemIds)
                .setIsProblemAllOne(isProblemAllOne);
        return extraProblemVo;
    }

    public static <T> T getSafetyPdfDTO(SqfwPdfCreateCommonBO pdfDTO) {
        AbstractCustomerPdfCreateField field = pdfDTO.getAbstractCustomerPdfCreateField();
        if (field == null) {
            throw new AppException("参数对象不能为空！");
        }
        return (T) field;
    }

    public static <T> T getPdfDTO(AbstractCustomerPdfCreateField field) {
        if (field == null) {
            throw new AppException("参数对象不能为空！");
        }
        return (T) field;
    }

    /**
     * 自定义渲染组件 word循环便利输出时，案例详见儿童探访pdf
     */
    public static Map<String, RenderPolicy> createCustomerRenderPolicy(String key) {
        Map<String,RenderPolicy> renderPolicyMap = Maps.newHashMap();
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        renderPolicyMap.put(key, policy);
        return renderPolicyMap;
    }

    public static List<SafeCheckTaskParamDataDTO> problemToSafeChecks(List<ProblemParamDTO> problemDefaults) {
        List<SafeCheckTaskParamDataDTO> defaultValues = new ArrayList<>();
        for (ProblemParamDTO p : problemDefaults) {
            SafeCheckTaskParamDataDTO safe = new SafeCheckTaskParamDataDTO();
            safe.setKey(p.getKey()).setFields(p.getFields()).setRiskCode(p.getRiskCode()).setRiskDesc(p.getRiskDesc());
            defaultValues.add(safe);
        }
        return defaultValues;
    }

}
